/* 

  VOTable parser


  Copyright © 2010 - 2011 F.Hroch (hroch@physics.muni.cz)

  This file is part of Munipack.

  Munipack is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.
  
  Munipack is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with Munipack.  If not, see <http://www.gnu.org/licenses/>.


  Reference:

  http://www.ivoa.net/Documents/VOTable/20091130/REC-VOTable-1.2.html

*/

#include <wx/wx.h>
#include <wx/xml/xml.h>
#include <wx/url.h>
#include <map>
#include <vector>


class VOInfoBasic {
public:
  VOInfoBasic(const wxXmlNode *node);

protected:

  wxString description;
  std::vector<wxString> links;
  std::map<wxString,wxString> params;

};

class VOInfo : public VOInfoBasic
{
public:
  VOInfo(const wxXmlNode *node): VOInfoBasic(node) {}
};

class VOParam : public VOInfoBasic
{
public:
  VOParam(const wxXmlNode *node): VOInfoBasic(node) {}
};

class VOField : public VOInfoBasic
{
public:
  VOField(const wxXmlNode *node): VOInfoBasic(node) {}
  wxString GetLabel() const;
  wxString GetType() const;
  wxString GetUnit() const;
};


class VOGroup {
public:
  VOGroup(const wxXmlNode *node);

  //private:

  wxString description;
  std::vector<VOParam> params;
  std::vector<wxString> refs;

};


class VOTableData {
public:
  VOTableData();
  VOTableData(const wxXmlNode *node);

  //private:

  int nrows;
  std::vector<wxString> elements;
  std::vector<wxXmlNode *> rows;

};

class VOData {
public:
  VOData();
  VOData(const wxXmlNode *);

  //private:

  VOTableData table;
  wxXmlNode *tablenode;

};


class VOTableTable {
public:
  VOTableTable(const wxXmlNode *node);
  int RecordCount() const;
  std::vector<wxString> GetRecord(int) const;
  std::vector<wxString> GetColumn(int) const;


  //private:

  wxString description;
  std::vector<VOParam> params;
  std::vector<VOField> fields;
  std::vector<VOGroup> groups;
  std::vector<VOInfo> infos;
  std::vector<wxString> links;
  VOData data;

};


class VOResource {
public:
  VOResource(const wxXmlNode *node);

  //private:

  wxString description;
  std::vector<VOParam> params;
  std::vector<VOField> fields;
  std::vector<VOGroup> groups;
  std::vector<VOInfo> infos;
  std::vector<wxString> links;
  std::vector<VOTableTable> tables;

};


class VOTable: public wxXmlDocument
{
public:
  /*
  VOTable();
  VOTable(const wxString&);
  VOTable(const wxInputStream&);
  */
  VOTable(const wxXmlDocument&);
  VOTable(const wxURL&);

  // interface for human
  wxString GetDescription() const;
  std::vector<wxString> GetResources() const;
  void SetResource(int);
  std::vector<wxString> GetParams() const;
  std::vector<wxString> GetGroups() const;
  std::vector<wxString> GetInfos() const;

  std::vector<wxString> GetFields() const;
  std::vector<wxString> GetUnits() const;
  std::vector<wxString> GetTypes() const;
  int RecordCount() const;
  std::vector<wxString> GetRecord(int) const;
  std::vector<wxString> GetColumn(int) const;
  
  // interface for programmers

  void SetProjection(const wxString&);
  void SetProjectionCenter(double,double);
  void SetSize(double);
  void SetScale(double);
  void SetMaglim(double);
  void SetMagkey(const wxString&);

  bool Sort(const wxString&);

  //  bool IsOk() const;
  bool Save(const wxString&, const wxString&);
  bool Save(wxOutputStream&, const wxString&);


private:

  //  const wxXmlDocument& votable;
  
  //  bool isok;
  int index;
  wxString description;
  std::vector<VOParam> params;
  std::vector<VOGroup> groups;
  std::vector<VOResource> resources;
  std::vector<VOInfo> infos;

  wxString proj_type, mag_key;
  double proj_alpha, proj_delta, proj_scale, mag_limit;
  double canvas_size;

  bool Parse();
  std::vector<wxString> TypeTrafo(const std::vector<wxString>&);
  char **GetArray(const std::vector<wxString>&);
  bool SaveText(wxOutputStream&);
  bool SaveCSV(wxOutputStream&);
  bool SaveSVG(wxOutputStream&);
  bool SaveFITS(const wxString&);

  double ToDouble(const wxString&);
};

